package choreganizer;

import java.util.*;
import java.text.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Calendar;
import java.util.GregorianCalendar;


public class ChoreSchedule
extends JLabel
implements MouseListener, Cloneable
{
	
	private java.util.List<Integer> dayList;
	private String[] timeList;
	
	private Color origC;
	private ChoreData choreData;
	private ScheduleData scheduleData;
	
	
	
	public ChoreSchedule()
	{
		origC = getForeground();
		Font lFont = new Font( getFont().getName(), Font.BOLD, 11 );
		//Font lFont = new Font( getFont().getName(), Font.PLAIN, 11 );
		setFont( lFont );
		
		addMouseListener(this);
	}
	
	
	public void setChoreData(ChoreData choreData)
	{
		this.choreData = choreData;
		setToolTipText(choreData.getName());
	}
	
	
	public ChoreData getChoreData()
	{
		return choreData;
	}
	
	
	public void setScheduleData(ScheduleData scheduleData)
	{
		this.scheduleData = scheduleData;
	}
	
	
	public ScheduleData getScheduleData()
	{
		return scheduleData;
	}
	
	
	public String getText()
	{
		String retString = "";
		
		if (choreData != null)
			retString = choreData.getName();
		
		return retString;
	}
	
	
	
	
	
	public boolean hasDayOfMonth(int dayToFind)
	{
		for (Integer day: dayList)
		{
			if (day == dayToFind)
				return true;
		}
		return false;
	}
	
	
	public void createDayList(int userMonth, int userYear)
	{
		dayList = new java.util.Vector<Integer>();
		
		if ( scheduleData.getDayType() == ScheduleTypes.DayTypes.calendardays )
		{
			for ( String s: scheduleData.getScheduledDay() )
				dayList.add( Integer.decode(s) );
		}
		
		else if ( scheduleData.getDayType() == ScheduleTypes.DayTypes.specific )
		{
			GregorianCalendar calTime = new GregorianCalendar( userYear, userMonth, 1 );
			int maxDays = calTime.getActualMaximum( Calendar.DAY_OF_MONTH );

			// Loop through every day in the month
			for (int i=1; i <= maxDays; i++)
			{
				// Get the weekday of the current day
				int currDayOfWeek = calTime.get( Calendar.DAY_OF_WEEK );
				
				// Check to see if this day 
				for ( String s: scheduleData.getScheduledDay() )
					if ( currDayOfWeek == Integer.decode(s) )
						dayList.add( i );
				
				calTime.add( Calendar.DAY_OF_MONTH, 1 );
			}
		}
		
		else if ( scheduleData.getDayType() == ScheduleTypes.DayTypes.annual )
		{
			GregorianCalendar calTime = new GregorianCalendar( userYear, userMonth, 1 );
			int maxDays = calTime.getActualMaximum( Calendar.DAY_OF_MONTH );
			
			// Convert the string into a date (leave out the hour/min)
			Date startDate = new Date();
			try {
				startDate = new SimpleDateFormat("MM/dd/yyyy").parse( scheduleData.getStartDate() );
			} catch (Exception e) {
				System.err.println("Error in ChoreSchedule.createDayList()");
				System.err.println(e);
			}

			// Loop through the array of annual days to add from the start
			String[] addDaysStr = scheduleData.getScheduledDay();
			for (int x=0; x < addDaysStr.length; x++)
			{
				// Convert this annual day to an int
				int daysToAdd = Integer.decode(addDaysStr[x]);
				
				// Loop through all the days of the month
				for (int i=1; i <= maxDays; i++)
				{
					GregorianCalendar checkTime = new GregorianCalendar();
					checkTime.setTime( startDate );
					
					// Keep adding days to the start time to see if it's in this month/year
					while ( calTime.after(checkTime) )
					{
						checkTime.add( Calendar.DAY_OF_MONTH, daysToAdd );
						
						// If it is, add it
						if ( calTime.compareTo(checkTime) == 0 )
							dayList.add( i );
					}
					
					calTime.add( Calendar.DAY_OF_MONTH, 1 );
				}
				// Reset calTime
				calTime = new GregorianCalendar( userYear, userMonth, 1 );
			}
		}
		
	}
	
	
	// FINISH THIS
	//public String[] createTimeList()
	public void createTimeList()
	{
		String[] retStrings = new String[0];
		
		if (ScheduleTypes.TimeTypes.annual == scheduleData.getTimeType())
		{
			// WE SHOULD CHECK IF TODAYS DATE = SAME AS START, AND THEN 
			// ADD TO THE STARTING TIME
			// OTHERWISE, JUST ADD THE TIME TO THE START OF THE DAY (0)
			try {
				java.util.List<String> returnList = new java.util.Vector<String>();
				
				// Create calendars
				Calendar checkCal = Calendar.getInstance();
				Calendar addCal = Calendar.getInstance();
				// Set addCal's time to the beginning of the day
				addCal.setTime(new SimpleDateFormat("HH:mm").parse("00:00"));
				
				String[] annualHours = scheduleData.getScheduledTime();
				final int ahCount = annualHours.length;
				
				// Loop through each annual value
				// CURRENTLY, OUR GUI ONLY ALLOWS THE USER TO ENTER 1 ANNUAL VALUE
				for (int i=0; i < ahCount; i++)
				{
					Date addHours = new SimpleDateFormat("HH:mm").parse(annualHours[i]);
					
					// Add the dates (and get the actual time) until we roll over into a new day
					do {
						checkCal.setTime( addHours );
						addCal.add( Calendar.HOUR_OF_DAY, checkCal.get(Calendar.HOUR_OF_DAY) );
						addCal.add( Calendar.MINUTE, checkCal.get(Calendar.MINUTE) );
						
						// format the date w/ the added hours
						SimpleDateFormat formatter = new SimpleDateFormat("HH:mm"); 
						// put the date into the string vector
						returnList.add( formatter.format(addCal.getTime()) );
					} while (checkCal.get(Calendar.DAY_OF_MONTH) == addCal.get(Calendar.DAY_OF_MONTH));
					
					// Instead of doing a check each time, we'll just remove the last item
					// which will always be past the time
					returnList.remove(returnList.size()-1);
				}
				
				// turn the vector into a string array
				retStrings = returnList.toArray(new String[0]);
			
			} catch (Exception e) {
				System.err.println("Error in ChoreSchedule.getTimeList()");
				System.err.println(e);
			}
		}
		else if (ScheduleTypes.TimeTypes.specific == scheduleData.getTimeType())
		{
			retStrings = scheduleData.getScheduledTime();
		}
		
		timeList = retStrings;
		retStrings = null;
	}
	
	
	public String[] getTimeList()
	{
		if (scheduleData != null)
		{
			if (timeList == null)
			{
				createTimeList();
			}
			
			return timeList;
		}
		
		return new String[0];
	}
	
	
	public String toString()
	{
		StringBuilder sb = new StringBuilder();
		
		/*if (choreData != null)
			sb.append( choreData.toString() );
		if (scheduleData != null)
			sb.append( scheduleData.toString() );*/
		
		sb.append( choreData.getName() + "\n" );
		for (int i: dayList)
			sb.append( i + ", " );
		sb.append("\n");
		
		return sb.toString();
	}
	
	
	public Object clone( )  
	{
		try 
		{
			return super.clone( );
		} 
		catch (CloneNotSupportedException ex) 
		{
			throw new InternalError(ex.toString( ));
		}
	}
	
	
	
	
	
	public void mousePressed(MouseEvent e) 
	{
	}
	
	public void mouseReleased(MouseEvent e)
	{
	}
	
	public void mouseEntered(MouseEvent e) 
	{
		// We need to use e.getSource() to use Cloneable objects
		if (e.getSource() instanceof Component)
			((Component)e.getSource()).setForeground( Color.RED );
	}
	
	public void mouseExited(MouseEvent e) 
	{
		// We need to use e.getSource() to use Cloneable objects
		if (e.getSource() instanceof Component)
			((Component)e.getSource()).setForeground( origC );
	}
	
	public void mouseClicked(MouseEvent e)
	{
		// We need to use e.getSource() to use Cloneable objects
		if (e.getSource() instanceof Container)
		{
			Component c = ((Container)e.getSource()).getParent();
			while (!(c instanceof JFrame))
				c = c.getParent();
			
			new ChoreScheduleDialog( (JFrame)c, this );
		}
	}
	
}







class ChoreScheduleDialog
extends JDialog
implements ActionListener
{
	public ChoreScheduleDialog(JFrame frame, ChoreSchedule choreSched)
	{
		super(frame, "Chore Schedule Information", true);
		
		
		GridBagConstraints gbc = new GridBagConstraints();;
		GridBagLayout gbl = new GridBagLayout();
		
		JPanel all = new JPanel();
		all.setLayout( gbl );
		
		JLabel lbl_name = new JLabel("Name:",JLabel.RIGHT);
		gbc = new GridBagConstraints(0,0,1,1,0,0,GridBagConstraints.CENTER,GridBagConstraints.HORIZONTAL,new Insets(20,6,2,6),8,8);
		gbl.setConstraints(lbl_name, gbc);
		
		JLabel lbl_alert = new JLabel("Alert Type:",JLabel.RIGHT);
		gbc = new GridBagConstraints(0,1,1,1,0,0,GridBagConstraints.CENTER,GridBagConstraints.HORIZONTAL,new Insets(2,6,2,6),8,8);
		gbl.setConstraints(lbl_alert, gbc);
		
		JLabel lbl_id = new JLabel("Schedule ID:",JLabel.RIGHT);
		gbc = new GridBagConstraints(0,2,1,1,0,0,GridBagConstraints.NORTH,GridBagConstraints.HORIZONTAL,new Insets(2,6,2,6),8,8);
		gbl.setConstraints(lbl_id, gbc);
		
		JLabel lbl_time = new JLabel("Time(s):",JLabel.RIGHT);
		gbc = new GridBagConstraints(0,3,1,1,0,0,GridBagConstraints.NORTH,GridBagConstraints.HORIZONTAL,new Insets(2,6,2,6),8,8);
		gbl.setConstraints(lbl_time, gbc);
		
		JLabel lbl_desc = new JLabel("Description:",JLabel.RIGHT);
		gbc = new GridBagConstraints(0,4,1,1,0,0,GridBagConstraints.NORTH,GridBagConstraints.HORIZONTAL,new Insets(2,6,2,6),8,8);
		gbl.setConstraints(lbl_desc, gbc);
		
		JLabel lbl_notes = new JLabel("Notes:",JLabel.RIGHT);
		gbc = new GridBagConstraints(0,5,1,1,0,0,GridBagConstraints.NORTH,GridBagConstraints.HORIZONTAL,new Insets(2,6,2,6),8,8);
		gbl.setConstraints(lbl_notes, gbc);
		
		
		JTextField txtF_name = new JTextField(choreSched.getChoreData().getName(),15);
		txtF_name.setEditable(false);
		gbc = new GridBagConstraints(1,0,1,1,1,0,GridBagConstraints.CENTER,GridBagConstraints.HORIZONTAL,new Insets(20,6,2,6),8,8);
		gbl.setConstraints(txtF_name, gbc);
		                               
		ScheduleTypes.AlertTypes alT = choreSched.getScheduleData().getAlertType();
		JTextField txtF_alert = new JTextField(alT.toString(),15);
		txtF_alert.setEditable(false);
		gbc = new GridBagConstraints(1,1,1,1,1,0,GridBagConstraints.CENTER,GridBagConstraints.HORIZONTAL,new Insets(2,6,2,6),8,8);
		gbl.setConstraints(txtF_alert, gbc);
		
		JTextField txtF_id = new JTextField(choreSched.getScheduleData().getID(),15);
		txtF_id.setEditable(false);
		gbc = new GridBagConstraints(1,2,1,1,1,0,GridBagConstraints.CENTER,GridBagConstraints.HORIZONTAL,new Insets(2,6,2,6),8,8);
		gbl.setConstraints(txtF_id, gbc);
		
		JList list_times = new JList(choreSched.getTimeList());
		list_times.setVisibleRowCount(3);
		JScrollPane scr_times = new JScrollPane(list_times);
		gbc = new GridBagConstraints(1,3,1,1,1,0,GridBagConstraints.CENTER,GridBagConstraints.HORIZONTAL,new Insets(2,6,2,6),8,8);
		gbl.setConstraints(scr_times, gbc);
		
		JTextArea txtA_desc = new JTextArea(choreSched.getChoreData().getDescription(),6,15);
		JScrollPane scr_desc = new JScrollPane(txtA_desc);
		txtA_desc.setEditable(false);
		gbc = new GridBagConstraints(1,4,1,1,1,0,GridBagConstraints.CENTER,GridBagConstraints.HORIZONTAL,new Insets(2,6,2,6),8,8);
		gbl.setConstraints(scr_desc, gbc);
		
		JTextArea txtA_notes = new JTextArea(choreSched.getChoreData().getNotes(),6,15);
		JScrollPane scr_notes = new JScrollPane(txtA_notes);
		txtA_notes.setEditable(false);
		gbc = new GridBagConstraints(1,5,1,1,1,0,GridBagConstraints.CENTER,GridBagConstraints.HORIZONTAL,new Insets(2,6,2,6),8,8);
		gbl.setConstraints(scr_notes, gbc);
		
		
		all.add(lbl_name);
		all.add(lbl_alert);
		all.add(lbl_id);
		all.add(lbl_time);
		all.add(lbl_desc);
		all.add(lbl_notes);
		
		all.add(txtF_name);
		all.add(txtF_alert);
		all.add(txtF_id);
		all.add(scr_times);
		all.add(scr_desc);
		all.add(scr_notes);
		
		JButton close = new JButton("Close");
		close.addActionListener(this);
		JPanel closeP = new JPanel( new FlowLayout(FlowLayout.RIGHT) );
		closeP.add( close );
		

		JScrollPane scr_all = new JScrollPane( all );
		scr_all.getVerticalScrollBar().setUnitIncrement(10);
		scr_all.setBorder( BorderFactory.createEmptyBorder(0,0,0,0) );
		getContentPane().setLayout( new BorderLayout() );
		getContentPane().add( scr_all, BorderLayout.CENTER );
		getContentPane().add( closeP, BorderLayout.PAGE_END );

		
		setSize(370,400);
		Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
		setLocation( (screen.width - getSize().width)/2, (screen.height - getSize().height)/2 );
      setResizable( false );
      setVisible( true );
	}

	public void actionPerformed(ActionEvent e)
	{
		setVisible(false);
		dispose();
	}
}